
#ifndef XBEESERIAL_H
#define XBEESERIAL_H

#include "mbed.h"
#include "platform.h"
#include <vector>
#include <map>
#include <string>

#ifdef MBED_RPC
#include "rpc.h"
#endif

#include "XBeeResponse.h"
#include "XBeeRequest.h"
#include "XBeeHandlerPointer.h"

const char API_PACKET_START = 0x7E;

void addArrayToArray(char* array, const char* subArray, int startIndex, int length);
char* getSubArray(char* array, int startIndex, int length);
unsigned long bytesToInt64(char* b);
unsigned short bytesToInt16(char* b);

char* int64ToBytes(unsigned long num);
char* int16ToBytes(unsigned short num);

class XBeeSerial : public Serial {
private:
    char buffer[255];
    vector<XBeeResponse*> respVector;
    Serial *debugSer;
    
    map<char, XBeeHandlerPointer> handlerMap;
    
public:
    XBeeSerial(PinName tx=p28, PinName rx=p27);
    void setDebugger(Serial* debugSer);
    void debug(const char* format, ...);
    
    void closeOut();
    bool hasData();
    XBeeResponse* getResponse();
    
    void sendLocalMessage(char apiID, char frameID, const string& msg);
    void sendLocalMessage(char apiID, char frameID, const char* msg, int msgLen);
    
    // Senders for 16-bit addresses
    void sendRemoteMessage(char apiID, char frameID, unsigned short destAddr16, const string& msg);
    void sendRemoteMessage(char apiID, char frameID, unsigned short destAddr16, const char* msg, int msgLen);
    
    // Helper methods for the various types of messages
    void sendTX(char frameID, unsigned short destAddr16, const char* msg, int msgLen);
    
    // Senders for 64-bit addresses
    void sendRemoteMessage(char apiID, char frameID, unsigned long destAddr64, const string& msg);
    void sendRemoteMessage(char apiID, char frameID, unsigned long destAddr64, const char* msg, int msgLen);
    
    void sendRequest(XBeeRequest*);
    void writeChars(char* buffer, int len);
    
    void rxHandler();
    void attachHandler(char apiID, void (*fptr)(XBeeResponse*));
    
    bool enforceChecksum;
};

#endif